﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using Quellenverwaltung.Data.Source;
using MsWord = Microsoft.Office.Interop.Word;

namespace Quellenverwaltung.Word
{
    class CitationHelper
    {
        public static MsWord.Application Application {get; set;}
        public MsWord.Document Document {get; set;}

        //object paramDocumentPath = @"Path\Biblio Citation.docx";
        object paramMissing = Type.Missing;
        object paramWdUnits = MsWord.WdUnits.wdStory;
        object paramWdMovementType = MsWord.WdMovementType.wdMove;
        object paramWdFieldTypeCitation = MsWord.WdFieldType.wdFieldCitation;
        object paramWdFieldTypeBiblio = MsWord.WdFieldType.wdFieldBibliography;
        //object paramBiblioSourceTag = "Mor01";
        
        public CitationHelper()
        {
            Document = Application.ActiveDocument;
        }

        public String addBook(Book book)
        {
            book.Tag = buildSourceTag(book);
            book.RefOrder = "1";

            String xmlSource = serialiseBookSource(book);
            Document.Bibliography.Sources.Add(xmlSource);

            return book.Tag;
        }

        public String addWebsite(Website website)
        {
            website.Tag = buildSourceTag(website);
            website.RefOrder = "1";

            String xmlSource = serialiseWebsiteSource(website);
            Document.Bibliography.Sources.Add(xmlSource);

            return website.Tag;
        }

        public String addJournal(ArticleInAPeriodical journal)
        {
            journal.Tag = buildSourceTag(journal);
            journal.RefOrder = "1";

            String xmlSource = serialiseJournalSource(journal);
            Document.Bibliography.Sources.Add(xmlSource);

            return journal.Tag;
        }

        public void addCitation(String sourceTag)
        {
            
            //Application.Selection.EndKey(ref paramWdUnits,
            //    ref paramWdMovementType);
            Application.Selection.Fields.Add(Application.Selection.Range,
                ref paramWdFieldTypeCitation, sourceTag,
                ref paramMissing);
        }

        private String serialiseBookSource(Book book)
        {
            XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
            namespaces.Add("b", "http://schemas.microsoft.com/office/word/2004/10/bibliography");

            XmlSerializer serializer = new XmlSerializer(typeof(Book));
            StringWriter stringWriter = new StringWriter();
            serializer.Serialize(stringWriter, book, namespaces);
            stringWriter.Close();

            return stringWriter.ToString().Replace("<?xml version=\"1.0\" encoding=\"utf-16\"?>","");
        }

        private String serialiseWebsiteSource(Website website)
        {
            XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
            namespaces.Add("b", "http://schemas.microsoft.com/office/word/2004/10/bibliography");

            XmlSerializer serializer = new XmlSerializer(typeof(Website));
            StringWriter stringWriter = new StringWriter();
            serializer.Serialize(stringWriter, website, namespaces);
            stringWriter.Close();

            return stringWriter.ToString().Replace("<?xml version=\"1.0\" encoding=\"utf-16\"?>", "");
        }

        private String serialiseJournalSource(ArticleInAPeriodical journal)
        {
            XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
            namespaces.Add("b", "http://schemas.microsoft.com/office/word/2004/10/bibliography");

            XmlSerializer serializer = new XmlSerializer(typeof(ArticleInAPeriodical));
            StringWriter stringWriter = new StringWriter();
            serializer.Serialize(stringWriter, journal, namespaces);
            stringWriter.Close();

            return stringWriter.ToString().Replace("<?xml version=\"1.0\" encoding=\"utf-16\"?>", "");
        }

        private String buildSourceTag(Source source)
        {
            String tagYear = source.Year;
            if (!String.IsNullOrEmpty(tagYear) && tagYear.Length > 2)
            {
                tagYear = tagYear.Substring(tagYear.Length - 2);
            }
            String tagName = "";

            if (source.Author != null &&
                source.Author.Author != null &&
                source.Author.Author.NameList != null &&
                source.Author.Author.NameList.Count > 0)
            {
                int length = 3;
                if (source.Author.Author.NameList[0].Last.Length < 3)
                {
                    length = source.Author.Author.NameList[0].Last.Length;
                }
                tagName = source.Author.Author.NameList[0].Last.Substring(0,length).ToUpper();
            }
            else
            {
                tagName = source.Title.Substring(0, 3);
            }

            String tag = tagName + tagYear;
            String tagCheck = tagName + tagYear;
            int tagCheckCount = 0;

            bool check = true;
            while (check)
            {
                System.Collections.IEnumerator en = Document.Bibliography.Sources.GetEnumerator();

                bool found = false;
                while (en.MoveNext())
                {
                    Microsoft.Office.Interop.Word.Source currsource = (Microsoft.Office.Interop.Word.Source)en.Current;
                    if (currsource.Tag.Contains(tag))
                    {
                        found = true;
                    }
                }
                if (found)
                {
                    tag = tagCheck + tagCheckCount;
                    tagCheckCount++;
                }
                else
                {
                    check = false;
                }
            }

            return tag;
        }
    }
}
